#include<iostream>
#include "Ringqueue.hpp"
#include "task.hpp"
#include <unistd.h>

//不断产生任务
void* Product(void*args)
{
    Ringqueue<task> *bq=static_cast<Ringqueue<task>*>(args);
    while(1)
    {
        int data1=rand()%10+1;
        int data2=rand()%10;
        char oper=opers[rand()%4];
        task _task(data1,data2,oper);
        bq->Push(_task);
        printf("生产了一个任务: %s,thread id: %d\n ",_task.GetTask().c_str(),pthread_self());
        sleep(1);
    }
}

//不断解决任务
void* Consumer(void*args)
{
    Ringqueue<task> *bq=static_cast<Ringqueue<task>*>(args);
    while(1)
    {
        //std::cout<<",,,,"<<std::endl;
        task _task=bq->Pop();
        _task.run();
        printf("处理任务: %s ,运算结果是: %s ,thread id: %d\n ",_task.GetTask().c_str(),_task.GetResult().c_str(),pthread_self());
        sleep(1);
    }
}


int main()
{
    srand(time(nullptr));
    Ringqueue<task>*bq=new Ringqueue<task>(10);

    pthread_t c[3],p[5];

    for(int i=0;i<5;i++)
    {
        pthread_create(p+i,nullptr,Product,bq); //传入的bq得在堆空间
    }
    
    for(int i=0;i<3;i++)
    {
        pthread_create(c+i,nullptr,Consumer,bq); 
    }


    for(int i=0;i<5;i++)
    {
        pthread_join(p[i],nullptr);
    }

    for(int i=0;i<3;i++)
    {
        pthread_join(c[i],nullptr);
    }

    return 0;
}


/*
// 生产者不断生产数据
void *productor(void *args)
{
    Ringqueue<int> *rqp = static_cast<Ringqueue<int> *>(args);
    while (true)
    {
        int data = rand() % 10;
        rqp->Push(data);
        std::cout << "pthread[" << pthread_self() << "]" << " 生产了一个数据: " << data << std::endl;
        sleep(1);
    }
}
// 消费者不断消费数据
void *consumer(void *args)
{
    Ringqueue<int> *rqp = static_cast<Ringqueue<int> *>(args);
    while (true)
    {
        int data = rqp->Pop();
        std::cout << "pthread[" << pthread_self() << "]" << " 消费了一个数据: " << data << std::endl;
    }
}
int main()
{
    srand((unsigned long)time(nullptr) ^ getpid());
    Ringqueue<int> rq(10);
    pthread_t c1, c2, c3, p1, p2, p3;
    pthread_create(&p1, nullptr, productor, &rq);
    pthread_create(&p2, nullptr, productor, &rq);
    pthread_create(&p3, nullptr, productor, &rq);
    pthread_create(&c1, nullptr, consumer, &rq);
    pthread_create(&c2, nullptr, consumer, &rq);
    pthread_create(&c3, nullptr, consumer, &rq);
 
    pthread_join(c1, nullptr);
    pthread_join(c2, nullptr);
    pthread_join(c3, nullptr);
    pthread_join(p1, nullptr);
    pthread_join(p2, nullptr);
    pthread_join(p3, nullptr);
 
    return 0;
}
*/

/*
using namespace std;

struct ThreadData
{
    Ringqueue<task> *rq;
    std::string threadname;
};

void *Productor(void *args)
{
    // sleep(3);
    ThreadData *td = static_cast<ThreadData*>(args);
    Ringqueue<task> *rq = td->rq;
    std::string name = td->threadname;
    int len = 4;
    while (true)
    {
        // 1. 获取数据
        int data1 = rand() % 10 + 1;
        usleep(10);
        int data2 = rand() % 10;
        char op = opers[rand() % len];
        task t(data1, data2, op);

        // 2. 生产数据
        rq->Push(t);
        cout << "Productor task done, task is : " << t.GetTask() << " who: " << name << endl;

        sleep(1);
    }
    return nullptr;
}

void *Consumer(void *args)
{
    ThreadData *td = static_cast<ThreadData*>(args);
    Ringqueue<task> *rq = td->rq;
    std::string name = td->threadname;

    while (true)
    {
        // 1. 消费数据
        task t;
        rq->Pop(&t);
       
        // 2. 处理数据
        
        cout << "Consumer get task, task is : " << t.GetTask() << " who: " << name << " result: " << t.GetResult() << endl;
        // sleep(1);

    }
    return nullptr;
}

int main()
{
    srand(time(nullptr) ^ getpid());
    Ringqueue<task> *rq = new Ringqueue<task>(5);

    pthread_t c[5], p[3];

    for (int i = 0; i < 1; i++)
    {
        ThreadData *td = new ThreadData();
        td->rq = rq;
        td->threadname = "Productor-" + std::to_string(i);

        pthread_create(p + i, nullptr, Productor, td);
    }

    for (int i = 0; i < 1; i++)
    {
        ThreadData *td = new ThreadData();
        td->rq = rq;
        td->threadname = "Consumer-" + std::to_string(i);

        pthread_create(c + i, nullptr, Consumer, td);
    }

    for (int i = 0; i < 1; i++)
    {
        pthread_join(p[i], nullptr);
    }
    for (int i = 0; i < 1; i++)
    {
        pthread_join(c[i], nullptr);
    }

    return 0;
}

*/